package leetcode.offer;

import java.util.Stack;

@SuppressWarnings("all")
public class _227_基本计算器II_单栈 {

    /**
     * 给你一个字符串表达式 s ，请你实现一个基本计算器来计算并返回它的值
     * 整数除法仅保留整数部分
     * 输入：s = "3+2*2"
     * 输出：7
     * 说明：表达式中的所有整数都是非负整数
     */
    public static int calculate(String s) {
        Stack<Integer> stack = new Stack<>();
        // 数字前的运算符，初始为正数
        char preSign = '+';
        // 当前的数字
        int num = 0;
        // 字符串长度范围
        int n = s.length() - 1;
        // i要么指向一个数字，要么指向一个运算符
        for (int i = 0; i <= n; i++) {
            // 将字符转换为数字，考虑到两位数、三位数的情况，需要累乘
            if (Character.isDigit(s.charAt(i))) {
                num = num * 10 + s.charAt(i) - '0';
            }
            // 如果遇到符号就看一下前一个数字的运算符号: 加减都压栈、乘除都弹栈
            if (!Character.isDigit(s.charAt(i)) && s.charAt(i) != ' ' || i == n) {
                switch (preSign) {
                    // 对于加减号后的数字，将其直接压入栈中
                    case '+':
                        stack.push(num);
                        break;
                    case '-':
                        stack.push(-num);
                        break;
                    // 对于乘除号后的数字，可以直接与栈顶元素计算，并替换栈顶元素为计算后的结果
                    case '*':
                        stack.push(stack.pop() * num);
                        break;
                    default:
                        stack.push(stack.pop() / num);
                }
                // 处理完该数字后，更新 preSign 为当前遍历的字符
                preSign = s.charAt(i);
                num = 0;
            }
        }
        // 遍历完字符串 s 后，将栈中元素累加，即为该字符串表达式的值
        int ans = 0;
        while (!stack.isEmpty()) {
            ans += stack.pop();
        }
        return ans;
    }

    public static void main(String[] args) {
        System.out.println(calculate("3-2*2"));
        // 即使是负整数也能够正常计算
        System.out.println(calculate("-10+3-2*2"));
    }
}
